package com.qiangesoft.rdp.starter.captcha.core;

import com.qiangesoft.rdp.starter.captcha.config.CaptchaProperties;
import com.qiangesoft.rdp.starter.captcha.constant.CharTypeEnum;
import com.qiangesoft.rdp.starter.captcha.model.Base64Result;
import com.qiangesoft.rdp.starter.captcha.model.CaptchaParam;
import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;

import java.awt.*;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 验证码服务
 *
 * @author qiangesoft
 * @date 2023-09-19
 */
public class EasyCaptchaTemplateImpl implements EasyCaptchaTemplate {

    private CaptchaProperties captchaProperties;

    private CaptchaStore captchaStore;

    public EasyCaptchaTemplateImpl(CaptchaProperties captchaProperties, CaptchaStore captchaStore) {
        this.captchaProperties = captchaProperties;
        this.captchaStore = captchaStore;
    }


    @Override
    public String create(String key, OutputStream outputStream) {
        Captcha captcha = this.buildCaptcha(CaptchaParam.toQuery(captchaProperties));
        captcha.out(outputStream);
        String text = captcha.text();

        // 存储
        captchaStore.put(key, text);
        return text;
    }

    @Override
    public String create(String key, CaptchaParam captchaParam, OutputStream outputStream) {
        Captcha captcha = this.buildCaptcha(captchaParam);
        captcha.out(outputStream);
        String text = captcha.text();

        // 存储
        captchaStore.put(key, text);
        return text;
    }

    @Override
    public Base64Result create(String key) {
        Captcha captcha = this.buildCaptcha(CaptchaParam.toQuery(captchaProperties));
        String text = captcha.text();

        // 存储
        captchaStore.put(key, text);

        Base64Result base64Result = new Base64Result();
        base64Result.setCaptcha(text);
        base64Result.setBase64(captcha.toBase64());
        return base64Result;
    }

    @Override
    public Base64Result create(String key, CaptchaParam captchaParam) {
        Captcha captcha = this.buildCaptcha(captchaParam);
        String text = captcha.text();

        // 存储
        captchaStore.put(key, text);

        Base64Result base64Result = new Base64Result();
        base64Result.setCaptcha(text);
        base64Result.setBase64(captcha.toBase64());
        return base64Result;
    }

    @Override
    public boolean check(String key, String captcha) {
        String cacheCaptcha = captchaStore.get(key);
        if (cacheCaptcha == null) {
            return false;
        }
        if (!cacheCaptcha.equals(captcha)) {
            return false;
        }

        captchaStore.remove(key);
        return true;
    }

    /**
     * 构建验证码
     *
     * @param captchaParam
     * @return
     */
    private Captcha buildCaptcha(CaptchaParam captchaParam) {
        int width = captchaParam.getWidth();
        int height = captchaParam.getHeight();
        int length = captchaParam.getLength();
        CharTypeEnum charType = captchaParam.getCharType();
        Captcha captcha;
        switch (captchaParam.getCaptchaType()) {
            case ARITHMETIC:
                captcha = new ArithmeticCaptcha(width, height, length);
                break;
            case CHINESE:
                captcha = new ChineseCaptcha(width, height, length);
                break;
            case CHINESE_GIF:
                captcha = new ChineseGifCaptcha(width, height, length);
                break;
            case GIF:
                captcha = new GifCaptcha(width, height, length);
                break;
            case SPEC:
                captcha = new SpecCaptcha(width, height, length);
                break;
            default:
                captcha = new ArithmeticCaptcha(width, height, length);
        }
        try {
            captcha.setFont(captchaParam.getFontType().getCode(), captchaParam.getFontStyle(), captchaParam.getFontSize());
        } catch (IOException e) {
            throw new IllegalArgumentException(e);
        } catch (FontFormatException e) {
            throw new RuntimeException(e);
        }
        captcha.setCharType(charType.getCode());
        return captcha;
    }
}
